{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "01e2695a",
   "metadata": {},
   "source": [
    "| [01_base/07_列表推导式.ipynb](https://github.com/shibing624/python-tutorial/blob/master/01_base/07_列表推导式.ipynb)  | Python列表推导式  |[Open In Colab](https://colab.research.google.com/github/shibing624/python-tutorial/blob/master/01_base/07_列表推导式.ipynb) |\n",
    "\n",
    "\n",
    "# 列表推导式\n",
    "\n",
    "循环可以用来生成列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "2224f209",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[4, 4, 9]\n"
     ]
    }
   ],
   "source": [
    "values = [2, 2, 3]\n",
    "squares = []\n",
    "for x in values:\n",
    "    squares.append(x ** 2)\n",
    "print(squares)  # [4, 4, 9]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a4c969dc",
   "metadata": {},
   "source": [
    "列表推导式可以使用更简单的方法来创建这个列表："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "d72774b4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[9, 64, 100, 196]\n"
     ]
    }
   ],
   "source": [
    "values = [3, 8, 10, 14]\n",
    "squares = [x ** 2 for x in values]\n",
    "print(squares)  # [9, 64, 100, 196]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8aab9ebb",
   "metadata": {},
   "source": [
    "可以加入条件筛选，在上面的例子中，\n",
    "\n",
    "假如只想保留列表中不大于8的数的平方："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "6c20ed66",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[9, 64, 100]\n"
     ]
    }
   ],
   "source": [
    "squares = [x ** 2 for x in values if x <= 10]\n",
    "print(squares)  # [9, 64, 100]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc3d7744",
   "metadata": {},
   "source": [
    "平方的结果不大于100的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "415e0e56",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[9, 64]\n"
     ]
    }
   ],
   "source": [
    "squares = [x ** 2 for x in values if x ** 2 <= 80]\n",
    "print(squares)  # [9, 64]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "14064061",
   "metadata": {},
   "source": [
    "使用推导式生成集合和字典："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "afce0845",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{16, 49, 100}\n"
     ]
    }
   ],
   "source": [
    "values = [10, 21, 4, 7, 12]\n",
    "square_set = {x ** 2 for x in values if x <= 10}\n",
    "\n",
    "print(square_set)  # set([16, 49, 100])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "0f28e767",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{10: 100, 4: 16, 7: 49}\n"
     ]
    }
   ],
   "source": [
    "square_dict = {x: x ** 2 for x in values if x <= 10}\n",
    "print(square_dict)  # {10: 100, 4: 16, 7: 49}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "697e2610",
   "metadata": {},
   "source": [
    "计算上面例子中生成的列表中所有元素的和："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "629432fd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "65"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "total = sum([x ** 2 for x in values if x < 10])\n",
    "total  # 65"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7d2f0b44",
   "metadata": {},
   "source": [
    "但是，Python会生成这个列表，然后在将它放到垃圾回收机制中（因为没有变量指向它），\n",
    "\n",
    "这毫无疑问是种浪费。\n",
    "\n",
    "为了解决这种问题，与range()类似，Python使用产生式表达式来解决这个问题："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "f5af0789",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "65"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "total = sum(x ** 2 for x in values if x < 10)\n",
    "total  # 65"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7cd1dc3e",
   "metadata": {},
   "source": [
    "与上面相比，只是去掉了括号，但这里并不会一次性的生成这个列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "0346c01b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "list speed:  0.0003058910369873047\n"
     ]
    }
   ],
   "source": [
    "import time\n",
    "\n",
    "# 比较一下两者的用时：\n",
    "x = range(1000000)\n",
    "t1 = time.time()\n",
    "\n",
    "total = sum([x ** 3 for x in values if x < 10])\n",
    "print(\"list speed: \", time.time() - t1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "id": "9680edb6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "comprehension speed: 0.00015783309936523438\n"
     ]
    }
   ],
   "source": [
    "t2 = time.time()\n",
    "total = sum(x ** 3 for x in values if x < 10)\n",
    "print(\"comprehension speed:\", time.time() - t2)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ead82919",
   "metadata": {},
   "source": [
    "ipython 下可以输入:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "id": "a2c6ceab",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "327 ms ± 19.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
      "295 ms ± 10.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
     ]
    }
   ],
   "source": [
    "x = range(1000000)\n",
    "%timeit total = sum([i**2 for i in x])\n",
    "%timeit total = sum(i**2 for i in x)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27fee9aa",
   "metadata": {},
   "source": [
    "本节完。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}